package com.example.springcloud.order.service.saga;

import com.example.springcloud.order.entity.Order;
import com.example.springcloud.order.enums.OrderStatus;
import com.example.springcloud.order.feign.AccountServiceFeign;
import com.example.springcloud.order.feign.StorageServiceFeign;
import com.example.springcloud.order.mapper.OrderMapper;
import io.seata.saga.engine.StateMachineEngine;
import io.seata.saga.proctrl.ProcessContext;
import io.seata.saga.statelang.domain.ExecutionStatus;
import io.seata.saga.statelang.domain.StateMachineInstance;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 订单 Saga 服务
 * 实现正向操作和补偿操作
 */
@Slf4j
@Service
public class OrderSagaService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private StorageServiceFeign storageServiceFeign;

    @Autowired
    private AccountServiceFeign accountServiceFeign;

    @Autowired
    private StateMachineEngine stateMachineEngine;

    // ========== Saga 状态机执行入口 ==========

    /**
     * 执行 Saga 创建订单流程
     */
    public Order executeSaga(Long userId, Long productId, Integer count, BigDecimal money) {
        log.info("========执行 Saga 状态机：创建订单========");

        // 准备输入参数
        Map<String, Object> startParams = new HashMap<>();
        startParams.put("userId", userId);
        startParams.put("productId", productId);
        startParams.put("count", count);
        startParams.put("money", money);

        // 启动状态机
        StateMachineInstance inst = stateMachineEngine.start(
            "order-saga-state-machine",  // 状态机名称，对应 JSON 文件中的 Name
            null,  // 业务 ID，可以传 null
            startParams
        );

        // 判断执行结果
        if (ExecutionStatus.SU.equals(inst.getStatus())) {
            log.info("========Saga 状态机执行成功========");
            // 获取创建的订单 ID
            Long orderId = (Long) inst.getEndParams().get("orderId");
            Order order = orderMapper.selectById(orderId);
            return order;
        } else {
            log.error("========Saga 状态机执行失败，已自动补偿========");
            log.error("失败原因：{}", inst.getException());
            throw new RuntimeException("订单创建失败：" + inst.getException());
        }
    }

    // ========== 正向操作（Forward Actions）==========

    /**
     * 正向操作1：创建订单
     */
    public Map<String, Object> createOrder(Long userId, Long productId, Integer count, BigDecimal money) {
        log.info("【Saga 正向操作】创建订单：userId={}, productId={}, count={}, money={}",
                userId, productId, count, money);

        // 创建订单
        Order order = new Order();
        order.setUserId(userId);
        order.setProductId(productId);
        order.setCount(count);
        order.setMoney(money);
        order.setStatus(OrderStatus.CREATING.getCode());
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());

        orderMapper.insert(order);
        log.info("订单创建成功，订单ID: {}", order.getId());

        // 返回结果（用于下一个状态）
        Map<String, Object> result = new HashMap<>();
        result.put("orderId", order.getId());
        return result;
    }

    /**
     * 正向操作2：扣减库存
     */
    public Map<String, Object> deductStorage(Long productId, Integer count) {
        log.info("【Saga 正向操作】扣减库存：productId={}, count={}", productId, count);

        // 调用库存服务扣减库存
        storageServiceFeign.deduct(productId, count);
        log.info("库存扣减成功");

        return new HashMap<>();
    }

    /**
     * 正向操作3：扣减账户余额
     */
    public Map<String, Object> deductAccount(Long userId, BigDecimal money) {
        log.info("【Saga 正向操作】扣减余额：userId={}, money={}", userId, money);

        // 调用账户服务扣减余额
        accountServiceFeign.deduct(userId, money);
        log.info("余额扣减成功");

        return new HashMap<>();
    }

    /**
     * 正向操作4：完成订单
     */
    public Map<String, Object> finishOrder(Long orderId) {
        log.info("【Saga 正向操作】完成订单：orderId={}", orderId);

        // 更新订单状态为已完成
        Order order = orderMapper.selectById(orderId);
        if (order != null) {
            order.setStatus(OrderStatus.FINISHED.getCode());
            order.setUpdateTime(LocalDateTime.now());
            orderMapper.updateById(order);
            log.info("订单状态更新为已完成");
        }

        return new HashMap<>();
    }

    // ========== 补偿操作（Compensation Actions）==========

    /**
     * 补偿操作1：取消订单
     */
    public void cancelOrder(Long orderId) {
        log.warn("【Saga 补偿操作】取消订单：orderId={}", orderId);

        if (orderId != null) {
            Order order = orderMapper.selectById(orderId);
            if (order != null) {
                order.setStatus(OrderStatus.CANCELLED.getCode());
                order.setUpdateTime(LocalDateTime.now());
                orderMapper.updateById(order);
                log.warn("订单已取消");
            }
        } else {
            log.warn("订单 ID 为空，跳过取消操作（空补偿）");
        }
    }

    /**
     * 补偿操作2：恢复库存
     */
    public void addStorage(Long productId, Integer count) {
        log.warn("【Saga 补偿操作】恢复库存：productId={}, count={}", productId, count);

        // 调用库存服务恢复库存
        // 注意：这里应该调用库存服务的恢复接口
        // 简化起见，这里直接记录日志
        log.warn("库存已恢复（实际应调用库存服务的补偿接口）");
    }

    /**
     * 补偿操作3：恢复账户余额
     */
    public void addAccount(Long userId, BigDecimal money) {
        log.warn("【Saga 补偿操作】恢复余额：userId={}, money={}", userId, money);

        // 调用账户服务恢复余额
        // 注意：这里应该调用账户服务的恢复接口
        // 简化起见，这里直接记录日志
        log.warn("余额已恢复（实际应调用账户服务的补偿接口）");
    }
}

